/**
 * @class JavaScript  树形菜单控件类。<br />
 * 此类功能包括：<br />
 * 树形菜单控件实现。
 * @constructor 构造函数
 * @throws MemoryException 如果没有足够的内存
 * @return 返回 DCalendarClass 对象
 */
function MenuTreeClass(){
	/**
	 * @private 私有函数
	 * 初始化设置params参数集参数值
	 * @param params Array 参数集 参数必须 是
	 * @return 无
	 * @type void
	 */
	var paramsDefault = function(params){
		 function param_default(pname, def) { 
		 	if (typeof params[pname] == "undefined"){
		 		params[pname] = def; 
		 	}
		 };
		 param_default("treeid",null);
		 param_default("arrtree",new Array());
		 param_default("treeclass","");
		 param_default("pnodeclass","");
		 param_default("nodeclass","");
		 
		 param_default("animated","normal");
		 param_default("collapsed",true);
		 param_default("unique",true);
	};
	/**
	 * 将HTML中的ul和li组成的数据转换成树形菜单<br />
	 * 相关参数集的说明如下：<br />
	 * treeid : "" String 树形菜单ID 参数必须 是<br />
	 * animated : "normal" 树节点显示展开和收起的速度，有三个值["slow","normal","fast"]可以设置，默认值为 "normal"<br />
	 * collapsed : true boolean 树的所有节点第一次显示时是否是只显示根节点，true只显示根节点，false不限制，默认值是true 参数必须 否<br />
	 * unique : true boolean 是否只允许一个树节点展开 true只允许一个树节点展开，false不限制，默认值是true 参数必须 否<br />
	 * @return 无
	 * @type void
	 */
	this.htmltree = function(params){
		paramsDefault(params);
		if(params.treeid != null){
			if(params.treeclass != "" && params.treeclass.indexOf("treeview") == -1){
				$("#" + params.treeid).treeview({
					animated: params.animated,
					collapsed: params.collapsed,
					unique: params.unique
				}).removeClass("treeview").addClass(params.treeclass);
			}else{
				$("#" + params.treeid).treeview({
					animated: params.animated,
					collapsed: params.collapsed,
					unique: params.unique
				});
			}
		}
	}
	/**
	 * 将传入的数据按jquery-treeview的规则生成相应的HTML代码，<br />
	 * 并加载相应的CSS和JavaScript实现树形菜单功能。<br />
	 * 相关参数集的说明如下：<br />
	 * treeid : "" String 树形菜单ID <br />
	 * arrtree : Object[] Array 树形菜单数据，存放MenuTreeBean对象的数组 <br />
	 * treeclass : "" String 树形菜单的总体风格 <br />
	 * pnodeclass : "" String 树形菜单节点风格 <br />
	 * nodeclass : "" String  树形菜单子节点风格 <br />
	 * animated : "normal" 树节点显示展开和收起的速度，有三个值["slow","normal","fast"]可以设置，默认值为 "normal"<br />
	 * collapsed : true boolean 树的所有节点第一次显示时是否是只显示根节点，true只显示根节点，false不限制，默认值是true 参数必须 否<br />
	 * unique : true boolean 是否只允许一个树节点展开 true只允许一个树节点展开，false不限制，默认值是true 参数必须 否<br />
	 * @param params Array 参数集 参数必须 是
	 * @return 无
	 * @type void
	 */
	this.jstree = function(params){
		paramsDefault(params);
		if(params.treeid != null && params.arrtree.length > 0){
			createTree(params.treeid,params.arrtree,params.treeclass,params.pnodeclass,params.nodeclass);
			if(params.treeclass != "" && params.treeclass.indexOf("treeview") == -1){
				$("#" + params.treeid).treeview({
					animated: params.animated,
					collapsed: params.collapsed,
					unique: params.unique
				}).removeClass("treeview").addClass(params.treeclass);
			}else{
				$("#" + params.treeid).treeview({
					animated: params.animated,
					collapsed: params.collapsed,
					unique: params.unique
				});
			}
		}
	}
	
	/**
	 * 根据传入的数据生成树形菜单
	 * @param treeid String 树形菜单ID 参数必须 是
	 * @param arrtree {@link MenuTreeBean} 数据树形菜单数据集 参数必须 是
	 * @param treeclass String 树形菜单风格  参数必须 是
	 * @param pnodeclass String 树形菜单父节点风格  参数必须 是
	 * @param nodeclass String 树形菜单子节点风格  参数必须 是
	 * @return 创建成功返回 true，失败返回 false
	 * @type boolean
	 */
	var createTree = function(treeid,arrtree,treeclass,pnodeclass,nodeclass){
		if( arrtree == '' || arrtree == 'undefined'){
			return false
		}
		if( arrtree.length < 1){
			return false;
		}
		try{
			//分析树形菜单数据
			analysisMenuTreeData(arrtree);
			//遍历输出树形结构
			traversalMenuTreeDate(arrtree,'0',treeid,treeclass,pnodeclass,nodeclass);
		}catch(ex){
			alert("创建树形菜单结构出错！");
			return false;
		}
		return true;
	}
	/**
	 * 遍历树形菜单数据并组输出树形结构。
	 * 为递归方法输出树形结构
	 * @param dtreeArray {@link MenuTreeBean} 数据树形菜单数据集 参数必须 是
	 * @param id String 树形菜单根节点标记 '0' 参数必须 是
	 * @param treeid String 树形菜单id 参数必须 是
	 * @param treeclass String 树形菜单风格  参数必须 是
	 * @param pnodeclass String 树形菜单父节点风格  参数必须 是
	 * @param nodeclass String 树形菜单子节点风格  参数必须 是
	 * @return 无
	 * @type void
	 */
	var traversalMenuTreeDate = function(dtreeArray,id,treeid,treeclass,pnodeclass,nodeclass){
		//alert("id:=" + id);
		var rootArray = queryMenuTreeData(dtreeArray,id);
		//对数据组进行排序
		
		rootArray.sort(function(obj1,obj2){
				if(obj1.getMenuOrderId() < obj2.getMenuOrderId()){
					return -1;
				}else if(obj1.getMenuOrderId() == obj2.getMenuOrderId()){
					return 0;
				}else if(obj1.getMenuOrderId() > obj2.getMenuOrderId()){
					return 1;
				}else{
					return obj1.getMenuOrderId() < obj2.getMenuOrderId();
				}
			});
		if(id == '0'){//out print root node
			if(treeclass != ''){
				document.write('<ul id="' + treeid + '" class="' + treeclass + '">');
			}else{
				document.write('<ul id="' + treeid + '">');
			}
		}
		var i = 0;
		for(i = 0; i < rootArray.length; i++){
			var dtreeBean = rootArray[i];
			if(dtreeBean.getHasChildNode()){//还有子节点
				if(pnodeclass != ''){
					document.write('<li><span class="' + pnodeclass + '">');
				}else{
					document.write('<li><span>');
				}
				var tempHref = '';
				if(dtreeBean.getMenuDo() != ''||dtreeBean.getMenuDo() != '#'){
					//tempHref = tempHref + 'href="' + dtreeBean.getMenuDo() + '" '
				}
				if(dtreeBean.getMenuTarget() != ''){
					tempHref = tempHref +  'target="' + dtreeBean.getMenuTarget() + '"';
				}
				if(tempHref != ''){
					document.write('<a ' + tempHref + ' >' + dtreeBean.getMenuName() + '</a>');
				}else{
					document.write(dtreeBean.getMenuName());
				}
				document.write('</span>');
				document.write('<ul>');
				traversalMenuTreeDate(dtreeArray,dtreeBean.getMenuId(),treeid,treeclass,pnodeclass,nodeclass);
				document.write('</ul>');
				document.write('</li>');
				
			}else{//没有子节点
				if(nodeclass != ''){
					document.write('<li><span class="' + nodeclass + '">');
				}else{
					document.write('<li><span>');
				}
				var tempHref = '';
				if(dtreeBean.getMenuDo() != ''){
					tempHref = tempHref + 'href="' + dtreeBean.getMenuDo() + '" '
				}
				if(dtreeBean.getMenuTarget() != ''){
					tempHref = tempHref +  'target="' + dtreeBean.getMenuTarget() + '"';
				}
				if(tempHref != ''){
					document.write('<a ' + tempHref + ' >' + dtreeBean.getMenuName() + '</a>');
				}else{
					document.write(dtreeBean.getMenuName());
				}
				document.write('</span>');
				document.write('</li>');
			}
		}
		if(id == '0'){
			document.write('</ul>');
		}
	}
	/**
	 * 分析处理树形菜单数据，形成树形数据结构的数据储存
	 * @param dtreeArray 未分析的树形菜单数据 即经过初始化之后的数据
	 * @return 返回分析后的树形菜单数据
	 * @type Array <{@link MenuTreeBean}>
	 */
	var analysisMenuTreeData = function(dtreeArray){
		if(dtreeArray.length < 1){
			return dtreeArray;
		}
		var i = 0;
		for(i = 0; i < dtreeArray.length; i++){
			var dtreeBean = dtreeArray[i];
			var treeid = dtreeBean.getMenuId();
			if(checkHasChildNode(dtreeArray,dtreeBean.getMenuId())){
				dtreeBean.setHasChildNode(true);
				//dtreeBean.setChildArray(queryMenuTreeData(dtreeArray,dtreeBean.getMenuId()));
			}else{
				dtreeBean.setHasChildNode(false);
			}
		}
	}
	/**
	 * 根据条件查找数据
	 * 返回一个数组
	 * @param dtreeArray Array <{@link MenuTreeBean}> 树形菜单对象数组
	 * @param id String 查找条件菜单父节点
	 * @return 返回查询结果集
	 * @type Array <{@link MenuTreeBean}>
	 */
	var queryMenuTreeData = function(dtreeArray,id){
		if(dtreeArray.length < 1 || id == '' || id == null || id == 'undefined'){
			return null;
		}
		var i = 0;
		var rs = new Array();
		var flag = 0;
		for(i = 0; i < dtreeArray.length; i++){
			var dtreeBean = dtreeArray[i];
			if(dtreeBean.getMenuPId() == id){
				rs[flag]=dtreeBean;
				flag = flag + 1;
			}
		}
		if(flag == 0){
			return null;
		}
		return rs;
	}
	/**
	 * 判断节点是否有子节点的
	 * @param dtreeArray Array <{@link MenuTreeBean}> 树形菜单对象数组
	 * @param id String 查找条件菜单父节点
	 * @return 返回判断结果，没有子节点返回 false，有子节点返回 true
	 * @type boolean
	 */
	var checkHasChildNode = function(dtreeArray,id){
		var i = 0;
		for(i = 0; i < dtreeArray.length; i++){
			var dtreeBean = dtreeArray[i];
			if(dtreeBean.getMenuPId() == id){
				return true;
			}
		}
		return false;
	}
	/**
	 * 创建树形菜单的数据集
	 * 返回Array {@link MenuTreeBean}
	 * 如果初始化数据失败返回空数据的Array对象
	 * @param params 树形菜单
	 * @return 返回一个数组对象，数组存放MenuTreeBean对象。
	 * @type Array
	 */
	this.initMenuTreeData = function(params){
		var dtreeArray = new Array();
		
		if( params == '' || params == 'undefined'){
			return dtreeArray
		}
		if( params.length < 1){
			return dtreeArray;
		}
		try{
			var i = 0;
			for(i = 0; i < params.length; i ++){
				var dtb = new MenuTreeBean();
				dtb.init(params[i].id,params[i].pid,params[i].code,params[i].pname,params[i].desc,params[i].pdo,params[i].target,params[i].orderid)
				dtreeArray[i] = dtb;
			}
			//对数据组进行排序
			dtreeArray.sort(function(obj1,obj2){
					if(obj1.getMenuId() < obj2.getMenuId()){
						return -1;
					}else if(obj1.getMenuId() == obj2.getMenuId()){
						return 0;
					}else if(obj1.getMenuId() > obj2.getMenuId()){
						return 1;
					}else{
						return obj1.getMenuId() < obj2.getMenuId();
					}
				});
		}catch(ex) {
			alert("ex:树形菜单数组排序出错!");
			dtreeArray = new Array();
		}
		//alert('dtreeArray.length :=' + dtreeArray.length);
		return dtreeArray;
	}
}
/**
 * @class JavaScript  树形菜单Bean类。<br />
 * 定义菜单的属性
 * @constructor 构造函数
 * @throws MemoryException 如果没有足够的内存
 * @return 返回 DCalendarClass 对象
 */
function MenuTreeBean(){
	/**
	 * 菜单id，id有一定的规则，方便菜单排序。
	 * 如: 100,101，102，103 其中100是根节点，而101 -103是100菜单的子菜单
	 * @type String
	 */
	var menuId;
	/**
	 * 获取菜单ID
	 * @return 返回菜单ID
	 * @type String
	 */
	this.getMenuId = function(){
		return menuId;
	}
	/**
	 * 菜单父节点id <br />
	 * 0 表示没有父节点，即为根节点，默认值为：0
	 * @type String
	 */
	var menuPId = "0";
	/**
	 * 获取菜单父节点ID
	 * @return 返回菜单父节点id
	 * @type String
	 */
	this.getMenuPId = function(){
		return menuPId;
	}
	/**
	 * 菜单编码
	 * @type String
	 */
	var menuCode = "";
	/**
	 * 获取菜单编码
	 * @return 返回菜单编码
	 * @type String
	 */
	this.getMenuCode = function(){
		return menuCode;
	}
	/**
	 * 菜单名称 即树形菜单显示的名称
	 * @type String 
	 */
	var menuName = "";
	/**
	 * 获取菜单名称
	 * @return 返回菜单名称
	 * @type String
	 */
	this.getMenuName = function(){
		return menuName;
	}
	/**
	 * 菜单描述
	 * @type String
	 */
	var menuDesc = "";
	/**
	 * 获取菜单描述
	 * @return 返回菜单描述
	 * @type String
	 */
	this.getMenuDesc = function(){
		return menuDesc;
	}
	/**
	 * 菜单链接 
	 * 如果菜单menuPId 为：0，则菜单链接不需要设置。
	 * @type String
	 */
	var menuDo = "";
	/**
	 * 获取菜单链接
	 * @return 返回菜单链接
	 * @type String
	 */
	this.getMenuDo = function(){
		return menuDo;
	}
	/**
	 * 菜单链接目标
	 * @type String
	 */
	var menuTarget = "";
	/**
	 * 获取菜单链接目标
	 * @return 返回菜单链接目标
	 * @type String
	 */
	this.getMenuTarget = function(){
		return menuTarget;
	}
	/**
	 * 菜单排序ID
	 * @type String
	 */
	var menuOrderId = "";
	/**
	 * 获取菜单排序ID
	 * @return 返回菜单排序ID
	 * @type String
	 */
	this.getMenuOrderId = function(){
		return menuOrderId;
	}
	
	/**
	 * 初始化设置菜单Bean对象中的属性值
	 * @return 无
	 * @type void
	 */
	this.init = function(id,pid,code,pname,desc,pdo,target,orderid){
		menuId = id;
		menuPId = pid;
		menuCode = code;
		menuName = pname;
		menuDesc = desc;
		menuDo = pdo;
		menuTarget = target;
		menuOrderId = orderid;
	}
	/**
	 * 是否有子节点，默认值为false
	 * @type boolean
	 */
	var hasChildNode = false;
	/**
	 * 获取菜单链接目标
	 * @return 返回菜单链接目标
	 * @type boolean
	 */
	this.getHasChildNode = function(){
		return hasChildNode;
	}
	/**
	 * 设置是否有子节点
	 * @param haschild boolean true：表示有子节点，false：表示没有了节点
	 * @return 无
	 * @type void
	 */
	this.setHasChildNode = function(haschild){
		hasChildNode = haschild;
	}
}

/**
 * @ignore 
 * 树形菜单组件类实例对象,即引入MenuTree.js文件，
 * 可以通过MenuTree.XXX()的方式使用树形菜单组件。
 */
var MenuTree = new MenuTreeClass();


